layui.define(['exbase', 'jquery', 'tree', 'layer'], function (exports) {
    var $ = layui.$;
    var exbase = layui.exbase;
    var tree = layui.tree;
    var form = layui.form

    const treeConfig = {
        elem: '',
        async: true,
        id: exbase.generateId("ex_tree"),
        url: '',
        method: "GET",
        contentType: "application/x-www-form-urlencoded",
        request: {},
        multiple: true,
        format: function (node_data) {
            return node_data;
        },
        rightMenus: []
    };

    class ExTree {
        constructor(config) {
            var that = this;
            this.config = Object.assign({}, treeConfig, config)
            exbase.createClass(".SELECTED_TREE_NODE", "background-color: #ff9900")

            if (!this.config.multiple) {
                var superOncheck = this.config.oncheck;
                this.config.oncheck = function (node) {
                    var elem = $(that.config.elem);
                    var checkboxes = elem.find('input[type=checkbox]')
                    var currentCheckbox = $(node.elem.find('input[type=checkbox]')[0])
                    var checked = currentCheckbox.prop('checked')
                    checkboxes.prop('checked', false)
                    if (!checked)
                        currentCheckbox.prop('checked', false)
                    else
                        currentCheckbox.prop('checked', true)
                    form.render('checkbox', 'LAY-tree-' + tree.index);
                    superOncheck && superOncheck()
                }
            }
        }

        render = function () {
            this.index = tree.render(this.config)
            this.events()
        }

        events = function () {
            var that = this;
            var ELEM_ENTRY = 'layui-tree-entry', ELEM_TEXT = 'layui-tree-txt',
                ELEM_MAIN = 'layui-tree-main',
                DISABLED = 'layui-disabled', ELEM_SPREAD = 'layui-tree-spread';
            var elem = $(this.config.elem);
            var elemMain = elem.find('.' + ELEM_MAIN)
            var elemText = elem.find('.' + ELEM_TEXT)


            function buildRightMenu(menus) {
                var tbl = "<table class='layui-table' style='margin:0px'>";
                menus.forEach(function (e) {
                    tbl += "<tr><td id=" + e.id + ">" + e.name + "</td></tr>";
                });
                tbl += "</table>";
                return tbl;
            }


            elemMain.on('click', function (event) {
                layer.close(that.lastLayer)
                elemText.removeClass("SELECTED_TREE_NODE")
                $(this).children('.' + ELEM_TEXT).addClass("SELECTED_TREE_NODE")
                return false;
            })

            this.config.rightMenus && elemMain.on('contextmenu', function (e) {
                var othis = $(this);
                var state = '';
                var etext = $(this).children('.' + ELEM_TEXT)[0]
                var treeEntry = othis.closest(".layui-tree-entry")[0]
                var treeSet = othis.closest(".layui-tree-set")[0]
                var data_id = $(treeSet).attr('data-id')
                var item = that.getData(that.config.data, data_id)

                var rightMenus = that.config.rightMenus;
                if (typeof rightMenus == "function") {
                    rightMenus = that.config.rightMenus({elem: $(etext), state: state, data: item});
                }
                rightMenus.forEach(function (e) {
                    e.id = exbase.generateId("tree_node_right_menu")
                })

                if (that.lastLayer) {
                    layer.close(that.lastLayer)
                }

                //判断是否禁用状态
                if ($(etext).hasClass(DISABLED)) return;
                that.lastLayer = layer.open({
                    type: 1,
                    title: false,
                    content: buildRightMenu(rightMenus),
                    offset: [event.pageY + "px", event.pageX + "px"],
                    closeBtn: 0,
                    shade: 0,
                    resize: false,
                    shadeClose: true
                })

                rightMenus.forEach(function (e) {
                    var id = e.id
                    var f = e.click
                    $("#" + id).on("click", function () {
                        f({elem: $(etext), state: state, data: item});
                        layer.close(that.lastLayer)
                    })
                });

                elemText.removeClass("SELECTED_TREE_NODE")

                $(etext).addClass("SELECTED_TREE_NODE")
                return false;
            });
            $(document).on("click contextmenu", function (event) {
                layer.close(that.lastLayer)
            })
        }

        getData = function (data, data_id) {
            var that = this;
            var result = null;
            if (data) {
                if (Array.isArray(data)) {
                    $.each(data, function (index, e) {
                        result = that.getData(e, data_id)
                        if (result) {
                            return false;
                        }
                    })
                } else {
                    if (data.id == data_id) {
                        return data;
                    } else {
                        result = that.getData(data.children, data_id)
                    }
                }
            }
            return result;
        }

        load = function () {
            var that = this;
            var data = that.config.request;
            if (that.config.contentType == "application/json") {
                data = JSON.stringify(that.config.request);
            }
            $.ajax({
                async: that.config.async,
                url: that.config.url,
                type: that.config.method,
                contentType: that.config.contentType,
                data: data,
                dataType: 'json',
                success: function (data) {
                    if (data.code != exbase.AJAX_SUCCESS_CODE) {
                        layer.msg(data.msg || "Error to load Tree", {icon: 2});
                        return;
                    }
                    var nodeData = that.formatAll(data.data);
                    that.config.data = nodeData
                    that.index = tree.render(that.config)
                    that.events()
                }
            })
        }
        formatAll = function (data) {
            var that = this;
            var returnData = data;
            if (that.config.format) {
                if (data.constructor == Array) {
                    returnData = new Array()
                    data.forEach(function (e) {
                        var node = that.config.format(e)
                        if (e.children) {
                            var newChildren = new Array()
                            e.children.forEach(function (child) {
                                newChildren.push(that.formatAll(child));
                            })
                            node.children = newChildren;
                        }
                        returnData.push(node);
                    })
                } else {
                    returnData = that.config.format(data)
                    if (data.children) {
                        var newChildren = new Array()
                        data.children.forEach(function (child) {
                            newChildren.push(that.formatAll(child))
                        })
                        returnData.children = newChildren;
                    }
                }
            }
            return returnData;
        }

        getSelectedNode = function () {
            var that = this;
            var ELEM_ENTRY = 'layui-tree-entry', ELEM_TEXT = 'layui-tree-txt',
                ELEM_MAIN = 'layui-tree-main',
                DISABLED = 'layui-disabled', ELEM_SPREAD = 'layui-tree-spread';
            var elem = $(this.config.elem);
            var selects = elem.find('.SELECTED_TREE_NODE')
            if (selects && selects.length > 0) {
                var etext = selects[0];
                var state = ''
                var treeSet = etext.closest(".layui-tree-set")
                var data_id = $(treeSet).attr('data-id')
                var item = that.getData(that.config.data, data_id)
                return {
                    elem: etext,
                    data: item,
                    state: state
                }
            } else {
                return null;
            }
        }

        getCheckedNode = function () {
            var that = this
            var elem = $(that.config.elem)
            //遍历节点找到选中索引
            var checkId = []
            elem.find('.layui-form-checked').each(function () {
                checkId.push($(this).prev()[0].value);
            });
            var arr = [];
            var f = function (arr, data, checkId) {
                $.each(data, function (index, item) {
                    $.each(checkId, function (i2, item2) {
                        if (item2 == item.id) {
                            arr.push(item)
                        }
                    })
                    if (item.children) {
                        f(arr, item.children, checkId)
                    }
                })
            }
            f(arr, that.config.data, checkId)
            return arr;
        }

    }

    exports('ExTree', ExTree);
})